{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Code to clean BigCode GitHub commits dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install ghdiff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datasets import load_dataset, concatenate_datasets\n",
    "from huggingface_hub import hf_hub_download\n",
    "import json\n",
    "import itertools\n",
    "from collections import Counter\n",
    "import re\n",
    "from difflib import SequenceMatcher\n",
    "import ghdiff\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_files = [\n",
    "    {\"rfilename\":\"data/diffs_10485761_11010048.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_1048577_1572864.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_11010049_11534336.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_11534337_12058624.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_12058625_12582912.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_12582913_13107200.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_13107201_13631488.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_13631489_14155776.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_14155777_14680064.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_14680065_15204352.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_15204353_15728640.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_15728641_16252928.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_1572865_2097152.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_16252929_16777216.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_1_524288.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_2097153_2621440.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_25165825_25690112.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_25690113_26214400.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_26214401_26738688.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_2621441_3145728.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_26738689_27262976.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_27262977_27787264.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_27787265_28311552.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_28311553_28835840.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_28835841_29360128.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_29360129_29884416.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_29884417_30408704.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_30408705_30932992.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_30932993_31457280.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_31457281_31981568.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_3145729_3670016.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_31981569_32505856.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_32505857_33030144.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_33030145_33554432.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_33554433_34078720.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_34078721_34603008.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_34603009_35127296.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_35127297_35651584.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_35651585_36175872.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_36175873_36700160.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_36700161_37224448.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_3670017_4194304.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_37224449_37748736.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_37748737_38273024.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_38273025_38797312.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_38797313_39321600.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_39321601_39845888.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_39845889_40370176.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_40370177_40894464.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_40894465_41418752.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_41418753_41943040.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_41943041_42467328.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_4194305_4718592.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_42467329_42991616.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_42991617_43515904.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_43515905_44040192.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_44040193_44564480.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_44564481_45088768.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_45088769_45613056.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_45613057_46137344.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_46137345_46661632.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_46661633_47185920.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_47185921_47710208.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_4718593_5242880.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_47710209_48234496.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_48234497_48758784.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_48758785_49283072.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_49283073_49807360.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_49807361_50331648.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_50331649_50855936.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_50855937_51380224.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_51380225_51904512.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_51904513_52428800.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_52428801_52953088.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_5242881_5767168.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_524289_1048576.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_52953089_53477376.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_53477377_54001664.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_54001665_54525952.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_54525953_55050240.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_55050241_55574528.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_55574529_56098816.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_56098817_56623104.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_56623105_57147392.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_57147393_57671680.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_57671681_58195968.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_5767169_6291456.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_58195969_58720256.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_58720257_59244544.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_59244545_59768832.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_59768833_60293120.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_60293121_60817408.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_60817409_61341696.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_61341697_61865984.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_61865985_62390272.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_62390273_62914560.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_62914561_63438848.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_6291457_6815744.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_63438849_63963136.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_63963137_64487424.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_64487425_65011712.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_65011713_65536000.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_65536001_66060288.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_66060289_66584576.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_66584577_67108864.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_6815745_7340032.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_7340033_7864320.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_7864321_8388608.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_8388609_8912896.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_8912897_9437184.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_9437185_9961472.jsonl\"},\n",
    "    {\"rfilename\":\"data/diffs_9961473_10485760.jsonl\"}\n",
    "]\n",
    "\n",
    "data_files = [data_file[\"rfilename\"] for data_file in data_files]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_out_github_login_the_stack_12 = '''INSERT OPT OUT HERE'''.splitlines()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_out_github_login_the_stack_12 = [el.lower() for el in opt_out_github_login_the_stack_12]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gh_diff(example):\n",
    "    example[\"gh_diff\"] = ghdiff.diff(example[\"old_contents\"],example[\"new_contents\"])\n",
    "    return example\n",
    "\n",
    "def get_line_diff_range(example):\n",
    "    old_file_start = 0\n",
    "    old_file_end = 0\n",
    "\n",
    "    new_file_start = 0\n",
    "    new_file_end = 0\n",
    "    \n",
    "    n_inserts = 0\n",
    "    n_deletes = 0\n",
    "    \n",
    "    for group in SequenceMatcher(None,example[\"old_contents\"].splitlines(),example[\"new_contents\"].splitlines()).get_grouped_opcodes():\n",
    "        group = [g for g in group if g[0]!=\"equal\"]\n",
    "        \n",
    "        for element in group:\n",
    "            if element[0]==\"insert\":\n",
    "                n_inserts += element[4]-element[3]\n",
    "            if element[0]==\"delete\":\n",
    "                n_deletes += element[2]-element[1] \n",
    "            if element[0]==\"replace\":\n",
    "                n_deletes += element[2]-element[1]\n",
    "                n_inserts += element[4]-element[3]\n",
    "\n",
    "        first, last = group[0], group[-1]\n",
    "        file1_range = (first[1], last[2])\n",
    "        file2_range = (first[3], last[4])\n",
    "        \n",
    "        old_file_start = min(file1_range[0], old_file_start)\n",
    "        old_file_end = max(file1_range[1], old_file_end)\n",
    "\n",
    "        new_file_start = min(file2_range[0], new_file_start)\n",
    "        new_file_end = max(file2_range[1], new_file_end)\n",
    "\n",
    "\n",
    "    # -2 for compatibility with gh_diff\n",
    "    example[\"old_change_start\"] = old_file_start\n",
    "    example[\"old_change_end\"] = old_file_end\n",
    "    example[\"old_change_range\"] = old_file_end - old_file_start\n",
    "\n",
    "    example[\"new_change_start\"] = new_file_start\n",
    "    example[\"new_change_end\"] = new_file_end\n",
    "    example[\"new_change_range\"] = new_file_end - new_file_start\n",
    "    \n",
    "    example[\"n_inserts\"] = n_inserts\n",
    "    example[\"n_deletes\"] = n_deletes\n",
    "    example[\"n_changes\"] = n_inserts + n_deletes\n",
    "    \n",
    "    return example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "112"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data_files)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from multiprocessing import Pool, Value\n",
    "\n",
    "counter = Value('i', 0)\n",
    "\n",
    "def init(args):\n",
    "    ''' store the counter for later use '''\n",
    "    global counter\n",
    "    counter = args\n",
    "\n",
    "def download_file(file):\n",
    "    global counter\n",
    "    print(\"start\")\n",
    "    file = hf_hub_download(\"bigcode/github-commits-diff\", file, repo_type=\"dataset\")\n",
    "    with counter.get_lock():\n",
    "        counter.value += 1\n",
    "    print(counter.value)\n",
    "    return file\n",
    "\n",
    "with Pool(16, initializer=init, initargs=(counter, )) as p:\n",
    "    _ = p.map(download_file, data_files[::2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "files = [hf_hub_download(\"bigcode/github-commits-diff\", file, repo_type=\"dataset\") for file in data_files[::2]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_folder = \"/home/leandro/.cache/huggingface/hub/datasets--bigcode--github-commits-diff/snapshots/7704908fcbfa44c37599f9bc83437beeec92d01b/\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "exclude = \"diffs_3145729_3670016.jsonl\" # error with file\n",
    "files = [file for file in files if not file.endswith(exclude)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "55"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(files)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from multiprocessing import Pool, Value\n",
    "\n",
    "counter = Value('i', 0)\n",
    "\n",
    "def init(args):\n",
    "    ''' store the counter for later use '''\n",
    "    global counter\n",
    "    counter = args\n",
    "\n",
    "def load_file(file):\n",
    "    global counter\n",
    "    print(\"start\")\n",
    "    file = load_dataset(\"/\".join(file.split(\"/\")[:-1]), data_files=file, split=\"train\")\n",
    "    with counter.get_lock():\n",
    "        counter.value += 1\n",
    "    print(counter.value)\n",
    "    return file\n",
    "\n",
    "with Pool(8, initializer=init, initargs=(counter, )) as p:\n",
    "    ds_list = p.map(load_file, files)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "ds = concatenate_datasets(ds_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "28835840"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(ds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ds = ds.filter(lambda x: len(x[\"old_contents\"])<100_000, num_proc=30)\n",
    "ds = ds.map(get_line_diff_range, num_proc=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes'],\n",
       "    num_rows: 27853656\n",
       "})"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "SHORT_SAMPLING = 0.1\n",
    "LONG_SAMPLING = 0.1\n",
    "\n",
    "JAVA_SAMPLING = 1.0\n",
    "\n",
    "MD_SAMPLING = 1.0\n",
    "\n",
    "\n",
    "SHORT_MSG_SAMPLING = 0.5\n",
    "\n",
    "DATA_SAMPLING = 1.0 #0.05\n",
    "DATA_EXT = {\"json\", \"yml\", \"xml\", \"html\"}\n",
    "\n",
    "BAD_SUB_MESSAGE = [\n",
    "    \"auto commit\",\n",
    "    \"update contributing\",\n",
    "    \"<?xml\"\n",
    "]\n",
    "\n",
    "BAD_MESSAGE = [\n",
    "    \"readme\",\n",
    "    \"update\",\n",
    "    \"dummy\",\n",
    "    \"updated\",\n",
    "    \"debug\",\n",
    "    \"test\",\n",
    "    \"update readme\",\n",
    "    \"update readme.md\",\n",
    "    \"updated readme.md\",\n",
    "    \"updated readme\",\n",
    "    \n",
    "]\n",
    "\n",
    "\n",
    "import random\n",
    "def commit_filter(example):\n",
    "    \n",
    "    if len(example[\"new_contents\"])==0:\n",
    "        return False\n",
    "    \n",
    "    if example[\"old_change_range\"]<=2:\n",
    "        if random.random()>SHORT_SAMPLING:\n",
    "            return False\n",
    "    \n",
    "    if example[\"old_change_range\"]>=200:\n",
    "        if random.random()>LONG_SAMPLING:\n",
    "            return False\n",
    "        \n",
    "    if example[\"old_file\"].split(\".\")[-1]==\"java\":\n",
    "        if random.random()>JAVA_SAMPLING:\n",
    "            return False\n",
    "        \n",
    "    if example[\"old_file\"].split(\".\")[-1]==\"md\":\n",
    "        if random.random()>MD_SAMPLING:\n",
    "            return False\n",
    "        \n",
    "    if example[\"old_file\"].split(\".\")[-1] in DATA_EXT:\n",
    "        if random.random()>DATA_SAMPLING:\n",
    "            return False\n",
    "        \n",
    "        \n",
    "    if len(example[\"subject\"])==0 or len(example[\"subject\"].split())==0:\n",
    "        return False\n",
    "\n",
    "    # remove samples with bad subwords\n",
    "    lower_subject = example[\"subject\"].lower()\n",
    "    for bad_msg in BAD_SUB_MESSAGE:\n",
    "        if bad_msg in lower_subject:\n",
    "            return False\n",
    "    \n",
    "    # remove samples with bad messages\n",
    "    for bad_msg in BAD_MESSAGE:\n",
    "        if bad_msg == lower_subject:\n",
    "            return False\n",
    "    \n",
    "    # subsample short messages\n",
    "    if len(lower_subject.split())<5:\n",
    "        if random.random()>SHORT_MSG_SAMPLING:\n",
    "            return False\n",
    "    \n",
    "    # version updates (e.g. v1.1.0)\n",
    "    if re.match(r\"(?:v)?\\d+\\.\\d+\\.\\d+(?=$|\\S)\", lower_subject):\n",
    "        return False\n",
    "\n",
    "    # high character/token ratio (e.g. hashes)\n",
    "    if len(example[\"subject\"])/len(example[\"subject\"].split())>20:\n",
    "        return False\n",
    "    \n",
    "    # weird messages that started with a whitespace and only contained one word\n",
    "    if lower_subject.startswith(\" \") and len(lower_subject.strip().split())==1:\n",
    "        return False\n",
    "    \n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "77ad2201f0644503900de9061edfd7a5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Filter (num_proc=30):   0%|          | 0/27853656 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ds_clean = ds.filter(commit_filter, num_proc=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes'],\n",
       "    num_rows: 12249044\n",
       "})"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_clean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Cumulative fraction')"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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cQAAAO7mdOfnhRde0Jo1a9SsWTONGjVKN998s2w2m9LS0vTqq6+qoKBAkydP9mStAAAAJeZ0+AkNDdWOHTv01FNPadKkSfYrPNtsNvXs2VMLFy5UaGioxwoFAABwB5cuchgZGank5GT98ssvOnLkiIwxatq0qWrUqOGp+gAAANzK5Ss8S1KNGjV0++23u7sWAAAAj3P6hGcAAIDy4IY6P/AdfK0dAABHdH4AAIClEH4AAIClEH4AAIClEH4AAIClEH4AAIClEH4AAICl8FX3coSvtQMAcH10fgAAgKUQfgAAgKUQfgAAgKUQfgAAgKUQfgAAgKUQfgAAgKUQfgAAgKVwnR8fxnV9AABwHZ0fAABgKYQfAABgKYQfAABgKYQfAABgKYQfAABgKYQfAABgKXzV3UfwtXYAANyDzg8AALAUwg8AALAUwg8AALAUwg8AALAUwg8AALAUwg8AALAUwg8AALAUrvNTBnFNHwAAPIfODwAAsBTCDwAAsBTCDwAAsBTCDwAAsBSvh5+FCxcqKipKAQEBiomJ0datW6+67po1a9S9e3fVrl1bQUFB6tChgz7++ONSrBYAAPg6r4aflStXasyYMZo8ebJSU1PVuXNnxcbGKiMjo9j1t2zZou7duys5OVl79uzRPffco169eik1NbWUKwcAAL7KZowx3nrx9u3bq23btlq0aJF9rHnz5urbt6+SkpKceo4WLVooLi5OU6dOdWr93NxcBQcHKycnR0FBQTdUt6fxVXcAABwV5p/TifkD3PL57bXOz4ULF7Rnzx716NHDYbxHjx7asWOHU89RWFiovLw81axZ86rr5OfnKzc31+EHAABYl9cucnjq1CkVFBQoNDTUYTw0NFQnT5506jnmzJmjs2fPasCAAVddJykpSdOnTy9RrZ5ElwcAgNLl9ROebTabw7IxpshYcd577z1NmzZNK1euVJ06da663qRJk5STk2P/OXHiRIlrBgAAvstrnZ+QkBBVrFixSJcnKyurSDfoSitXrtQTTzyhVatW6b777rvmuv7+/vL39y9xvQAAoHzwWuencuXKiomJUUpKisN4SkqKOnbseNXt3nvvPQ0dOlR///vf9eCDD3q6TAAAUM549camCQkJ+sMf/qB27dqpQ4cOeuONN5SRkaH4+HhJvx6y+uGHH/TOO+9I+jX4DB48WH/5y1905513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tttusy8PHTpUffv2LbUagRthubu6w9qysrI0ZcoUffjhh/rpp59Uo0YNtW7dWtOmTVOHDh28Xd51LVu2TFu3btWOHTsUEhKi4OBgb5dUpuzevVvVqlXzdhnlxo283/7yl7+Ia+eirCP8wFL69++vixcvatmyZWrUqJF++uknbdy4UT///LO3S3PK0aNH1bx5c0VHR3u7lDKpdu3a3i6hzLl48aL8/PxuaNsbeb8RyOELOOwFyzh9+rS2bdum2bNn65577lFkZKTuuOMOTZo0yeGu6DabTYsWLVJsbKyqVKmiqKgorVq1yuG5JkyYoGbNmqlq1apq1KiRpkyZoosXL9ofv3wo4N1331XDhg0VHBysgQMHKi8v75o1/uMf/1CLFi3k7++vhg0bas6cOfbHunbtqjlz5mjLli2y2Wzq2rXrVZ9n3bp1ateunQICAhQSEqKHH37Y4fFz585p2LBhCgwMVIMGDfTGG2+4fX55eXl67LHHVK1aNYWHh2vevHnq2rWrxowZY1/nwoULeu6551S3bl1Vq1ZN7du316ZNm+yPHz9+XL169VKNGjVUrVo1tWjRQsnJyVed95WHjWw2m9566y3169dPVatWVdOmTbVu3bqrbn/5Of70pz9d9fezadOmIoeA9u3bJ5vNpu+++06S9Pbbb+umm27Sv/71L918882qWrWqHnnkEZ09e1bLli1Tw4YNVaNGDT399NMqKChweP28vDwNGjRI1atXV0REhP761786PJ6Tk6M//vGPqlOnjoKCgtStWzft37/f/vjlfbNkyRI1atRI/v7+V+3EuOv99ltXHvbq2rWrRo8ereeee041a9ZUWFiYpk2b5tKc9u/fr3vuuUeBgYEKCgpSTEyMvvzyS6fqAYpV0huVAb7i4sWLpnr16mbMmDHm/PnzV11PkqlVq5Z58803zaFDh8wLL7xgKlasaA4ePGhf58UXXzTbt2836enpZt26dSY0NNTMnj3b/nhiYqKpXr26efjhh82BAwfMli1bTFhYmHn++eev+rpffvmlqVChgpkxY4Y5dOiQWbp0qalSpYr9pn/Z2dlmxIgRpkOHDiYzM/OqNzD817/+ZSpWrGimTp1qDh48aPbt22deeukl++ORkZGmZs2a5tVXXzWHDx82SUlJpkKFCiYtLc2t8xs+fLiJjIw0n3zyiTlw4IDp16+fCQwMNM8884x9nUGDBpmOHTuaLVu2mCNHjpg///nPxt/f33z77bfGGGMefPBB0717d/PVV1+Zo0ePmn/+85/XvBlxZGSkmTdvnn1ZkqlXr575+9//bg4fPmxGjx5tqlevfs2bP17v93P5hpS//PKLfZvLd+ZOT083xhizdOlS4+fnZ7p372727t1rNm/ebGrVqmV69OhhBgwYYL755hvzz3/+01SuXNmsWLHC4bUDAwNNUlKSOXTokHnllVdMxYoVzYYNG4wxv970sVOnTqZXr15m9+7d5ttvvzXjxo0ztWrVss8pMTHRVKtWzfTs2dPs3bvX7N+/3xQWFhaZp7veb4mJiaZ169b25SFDhpg+ffrYl++++24TFBRkpk2bZr799luzbNkyY7PZXJpTixYtzO9//3uTlpZmvv32W/P++++bffv2XXUfAtdD+IGlrF692tSoUcMEBASYjh07mkmTJpn9+/c7rCPJxMfHO4y1b9/ePPXUU1d93pdfftnExMTYlxMTE03VqlVNbm6ufWz8+PGmffv2V32OQYMGme7duzuMjR8/3tx666325Weeecbcfffd15xjhw4dzGOPPXbVxyMjI83vf/97+3JhYaGpU6eOWbRo0VW3cXV+ubm5xs/Pz6xatcr++OnTp03VqlXt4efIkSPGZrOZH374weG17r33XjNp0iRjjDEtW7Y006ZNu+Z8r5zbleHnhRdesC+fOXPG2Gw28+GHH17zOa71+3E2/EgyR44csa/z5JNPmqpVq5q8vDz7WM+ePc2TTz7p8Nr333+/Qz1xcXEmNjbWGGPMxo0bTVBQUJHw3rhxY/P6668bY37dN35+fiYrK+uqczTGfe83Z8LPXXfd5bDN7bffbiZMmOD0nAIDA83bb799zToAV3DYC5bSv39//fjjj1q3bp169uypTZs2qW3btnr77bcd1rvy5OcOHTooLS3Nvrx69WrdddddCgsLU/Xq1TVlyhRlZGQ4bNOwYUMFBgbal8PDw5WVlXXV2tLS0tSpUyeHsU6dOunw4cNFDo1cy759+3Tvvfdec51WrVrZ/22z2RQWFuZQW0nnd+zYMV28eFF33HGH/fHg4GDdfPPN9uW9e/fKGKNmzZqpevXq9p/Nmzfr6NGjkqTRo0dr5syZ6tSpkxITE/XVV185/Xsobq7VqlVTYGDgNffDldsU9/txRtWqVdW4cWP7cmhoqBo2bKjq1as7jF35vNd67+3Zs0dnzpxRrVq1HH5n6enp9t+ZJEVGRl73/Cd3vd+c8dvfp+T4XnFmTgkJCRo+fLjuu+8+zZo1y2GuwI3ghGdYTkBAgLp3767u3btr6tSpGj58uBITEzV06NBrbmez2SRJu3bt0sCBAzV9+nT17NlTwcHBWrFihcP5EpKKnGRqs9lUWFh41ec3xthf47djrqpSpcp117lWbe6Y3+W6rzWfwsJCVaxYUXv27FHFihUd1rscEIYPH66ePXtq/fr12rBhg5KSkjRnzhw9/fTT152jM3XeyDYVKlQoMpffng91ree4kVouryf9+jsLDw93OC/qsptuusn+b2e+8eau95szrjVvZ+Y0bdo0DRo0SOvXr9eHH36oxMRErVixQv369fNIvSj/6PzA8m699VadPXvWYWzXrl1Flm+55RZJ0vbt2xUZGanJkyerXbt2atq0qY4fP+6WOrZt2+YwtmPHDjVr1qxIOLiWVq1aaePGjTdchzvm17hxY/n5+emLL76wj+Xm5urw4cP25TZt2qigoEBZWVlq0qSJw09YWJh9vfr16ys+Pl5r1qzRuHHj9Oabb97w3NzhckclMzPTPrZv3z63Pf+13ntt27bVyZMnValSpSK/s5CQEJdex13vt5Jydk7NmjXT2LFjtWHDBj388MNaunRpqdWI8ofODywjOztbv/vd7zRs2DC1atVKgYGB+vLLL/Xyyy+rT58+DuuuWrVK7dq101133aXly5friy++0OLFiyVJTZo0UUZGhlasWKHbb79d69ev19q1a0tc37hx43T77bfrxRdfVFxcnHbu3KkFCxZo4cKFLj1PYmKi7r33XjVu3FgDBw7UpUuX9OGHH+q5555zant3zC8wMFBDhgzR+PHjVbNmTdWpU0eJiYmqUKGCvdvQrFkzPfbYYxo8eLDmzJmjNm3a6NSpU/r000/VsmVLPfDAAxozZoxiY2PVrFkz/fLLL/r000/VvHlzl2pxtyZNmqh+/fqaNm2aZs6cqcOHDxfpipXE9u3b9fLLL6tv375KSUnRqlWrtH79eknSfffdpw4dOqhv376aPXu2br75Zv34449KTk5W37591a5dO6dfx13vt5K63pxatGih8ePH65FHHlFUVJS+//577d69W/379y/VOlG+0PmBZVSvXl3t27fXvHnz1KVLF0VHR2vKlCkaMWKEFixY4LDu9OnTtWLFCrVq1UrLli3T8uXLdeutt0qS+vTpo7Fjx2rUqFG67bbbtGPHDk2ZMqXE9bVt21bvv/++VqxYoejoaE2dOlUzZsy47uG4K3Xt2lWrVq3SunXrdNttt6lbt276/PPPnd7eXfObO3euOnTooIceekj33XefOnXqpObNmysgIMC+ztKlSzV48GCNGzdON998s3r37q3PP/9c9evXlyQVFBRo5MiRat68ue6//37dfPPNpf7hfCU/Pz+99957+ve//63WrVtr9uzZmjlzptuef9y4cdqzZ4/atGmjF198UXPmzFHPnj0l/Xq4KDk5WV26dNGwYcPUrFkzDRw4UN99951CQ0Ndeh13vd9K6npzqlixorKzszV48GA1a9ZMAwYMUGxsrKZPn16qdaJ8sRlPHeQFfJTNZtPatWu5RL+bnT17VnXr1tWcOXP0xBNPeLscABbGYS8AHpGamqp///vfuuOOO5STk6MZM2ZIUpFDjABQ2gg/ADzmf//3f3Xo0CFVrlxZMTEx2rp1q8sn5gKAu3HYCwAAWAonPAMAAEsh/AAAAEsh/AAAAEsh/AAAAEsh/AAAAEsh/AAAAEsh/AAAAEsh/AAAAEsh/AAAAEv5fw/NgM+ztvKfAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist(ds_clean[\"old_change_range\"], bins=np.concatenate((np.linspace(0, 200, 101), [1e6])), cumulative=True, density=True);\n",
    "plt.xlim(0, 202)\n",
    "plt.ylim(0.0,1)\n",
    "plt.xlabel(\"Span of changes in number of lines\")\n",
    "plt.ylabel(\"Cumulative fraction\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Cumulative fraction')"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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4Ro8eLA+/PDD6i6tyg4dOqTmzZsrKipKI0eO1JEjRyrsW9u336lTp/SPf/xD48aNq/SBsVLt2X6/l5mZqZycHJdtFBAQoKuuuqrC76RU8XatbJmaIj8/Xw6HQ5dcckml/X755RdFRESoZcuWuvHGG5Wenn5hCqyizZs3q1mzZurQoYPuuece5ebmVtq/tm7DH3/8URs3btT48ePP2bembsOzfxcuxu+hrcLNsWPHVFxcXObBm6GhoWUeuFkqJyen3P5nzpzRsWPHqq1WTzDGKCEhQVdeeaW6du1aYb/w8HC99NJLeuutt7R+/Xp17NhRgwcP1tatWy9gte7p06ePXnvtNb333nt6+eWXlZOTo379+ikvL6/c/rV5+0nS22+/rePHj2vs2LEV9qlN2+9spd87K9/J0uWsLlMTnDx5UtOnT9eoUaMqfRjhpZdeqldffVXJycl6/fXXFRgYqP79++vQoUMXsFr3xcXFafXq1frggw+0YMEC7dq1S4MGDVJRUVGFy9TWbbhq1SoFBQXptttuq7RfTd2G5f0uXGzfQ8nLj1+oLmf/D9gYU+n/isvrX157TfPAAw/os88+00cffVRpv44dO6pjx47O6ZiYGB09elR//etfNXDgwOou05K4uDjnv7t166aYmBi1bdtWq1atUkJCQrnL1NbtJ0nLly9XXFycmjdvXmGf2rT9KmL1O1nVZbzp9OnTGjlypEpKSrR06dJK+/bt29flhNz+/furV69eeu6557R48eLqLtWy+Ph457+7du2q3r17KyIiQhs3bqw0BNS2bShJK1as0J133nnOc2dq6jas7HfhYvgelrLVnpsmTZrIx8enTKrMzc0tkz5LhYWFldvf19dXjRs3rrZaz9eDDz6o5ORkffjhh2rZsqXl5fv27ev1/2G4o379+urWrVuFtdbW7SdJ3377rf7zn/9owoQJlpetLduv9Eo3K9/J0uWsLuNNp0+f1ogRI5SZmanU1NRK99qUp06dOrr88strxTaVftubGBERUWm9tW0bStK2bdt08ODBKn0na8I2rOh34WL5Hv6ercKNv7+/oqOjnVeflEpNTVW/fv3KXSYmJqZM/02bNql3797y8/OrtlqryhijBx54QOvXr9cHH3ygqKioKq0nPT1d4eHhHq7O84qKipSRkVFhrbVt+/3eypUr1axZM91www2Wl60t2y8qKkphYWEu2+jUqVPasmVLhd9JqeLtWtky3lIabA4dOqT//Oc/VQrVxhjt3bu3VmxTScrLy9PRo0crrbc2bcNSy5cvV3R0tHr06GF5WW9uw3P9LlwM38MyvHEWc3V64403jJ+fn1m+fLk5cOCAmTx5sqlfv7755ptvjDHGTJ8+3dx1113O/keOHDH16tUzU6ZMMQcOHDDLly83fn5+Zt26dd4aQqXuu+8+ExISYjZv3myys7OdrxMnTjj7nD3GZ5991mzYsMF89dVX5vPPPzfTp083ksxbb73ljSFUaurUqWbz5s3myJEjZufOnebGG280QUFBttl+pYqLi03r1q3NtGnTysyrbduvsLDQpKenm/T0dCPJLFy40KSnpzuvFpo/f74JCQkx69evN/v37zd33HGHCQ8PNwUFBc513HXXXS5XNG7fvt34+PiY+fPnm4yMDDN//nzj6+trdu7cWaPGd/r0aXPzzTebli1bmr1797p8J4uKiioc35w5c8y7775rDh8+bNLT083dd99tfH19zccff3zBx2dM5WMsLCw0U6dONWlpaSYzM9N8+OGHJiYmxrRo0cIW27BUfn6+qVevnlm2bFm566jJ29Cd34Xa/j20ynbhxhhjnn/+eRMREWH8/f1Nr169XC6THjNmjLnqqqtc+m/evNn07NnT+Pv7m8jIyAo/3DWBpHJfK1eudPY5e4xPP/20adu2rQkMDDQNGzY0V155pdm4ceOFL94N8fHxJjw83Pj5+ZnmzZub2267zXzxxRfO+bV9+5V67733jCRz8ODBMvNq2/YrvVT97NeYMWOMMb9dhpqYmGjCwsJMQECAGThwoNm/f7/LOq666ipn/1Jr1641HTt2NH5+fubSSy/1WpirbHyZmZkVfic//PBD5zrOHt/kyZNN69atjb+/v2natKmJjY01aWlpF35w/09lYzxx4oSJjY01TZs2NX5+fqZ169ZmzJgxJisry2UdtXUblnrxxRdN3bp1zfHjx8tdR03ehu78LtT276FVDmP+39mXAAAANmCrc24AAAAINwAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFYIN0AtcuLECQ0fPlzBwcFyOBw6fvy45XVERkZq0aJFHq+tJqjtY6tp9bvzeZszZ44uu+wy5/TYsWM1bNiwC1YjUB5bPhUcqEhubq5mzZqld955Rz/++KMaNmyoHj16aM6cOYqJifF2eee0atUqbdu2TWlpaWrSpIlCQkK8XVKNsmvXLtWvX9/bZdhGVT5vf/vb38S9YeFthBtcVIYPH67Tp09r1apVatOmjX788Ue9//77+umnn7xdmlsOHz6sTp06qWvXrt4upUZq2rSpt0uocU6fPl3lh8hW5fNG4EZNwGEpXDSOHz+ujz76SE8//bSuueYaRURE6IorrtCMGTNcnsztcDi0bNkyxcXFqW7duoqKitLatWtd1jVt2jR16NBB9erVU5s2bTRr1iydPn3aOb90V/3f//53RUZGKiQkRCNHjlRhYWGlNb711lvq0qWLAgICFBkZqQULFjjnXX311VqwYIG2bt0qh8Ohq6++usL1JCcnq3fv3goMDFSTJk102223ucw/ceKExo0bp6CgILVu3VovvfSSx8dXWFioO++8U/Xr11d4eLieffZZXX311Zo8ebKzz6lTp/Too4+qRYsWql+/vvr06aPNmzc753/77be66aab1LBhQ9WvX19dunRRSkpKheM++7COw+HQK6+8oltvvVX16tVT+/btlZycXOHypev485//XOHfZ/PmzWUO0ezdu1cOh0PffPONJOnVV1/VJZdcon//+9/q2LGj6tWrp9tvv12//vqrVq1apcjISDVs2FAPPvigiouLXd6/sLBQo0aNUoMGDdS8eXM999xzLvPz8/P1pz/9Sc2aNVNwcLAGDRqkffv2OeeXbpsVK1aoTZs2CggIqHBPiqc+b7939mGpq6++WpMmTdKjjz6qRo0aKSwsTHPmzLE0pn379umaa65RUFCQgoODFR0drU8//dStenCR8u6jrYAL5/Tp06ZBgwZm8uTJ5uTJkxX2k2QaN25sXn75ZXPw4EHz+OOPGx8fH3PgwAFnnyeeeMJs377dZGZmmuTkZBMaGmqefvpp5/zExETToEEDc9ttt5n9+/ebrVu3mrCwMPPYY49V+L6ffvqpqVOnjpk3b545ePCgWblypalbt67z4Xd5eXnmnnvuMTExMSY7O9vk5eWVu55///vfxsfHx8yePdscOHDA7N271zz11FPO+REREaZRo0bm+eefN4cOHTJJSUmmTp06JiMjw6PjmzBhgomIiDD/+c9/zP79+82tt95qgoKCzEMPPeTsM2rUKNOvXz+zdetW8/XXX5u//OUvJiAgwHz11VfGGGNuuOEGM2TIEPPZZ5+Zw4cPm3/9618uD8I9W0REhHn22Wed05JMy5YtzT//+U9z6NAhM2nSJNOgQYMK/3bu/H1KH8L4888/O5cpfdp0ZmamMcaYlStXGj8/PzNkyBCzZ88es2XLFtO4cWMTGxtrRowYYb744gvzr3/9y/j7+5s33njD5b2DgoJMUlKSOXjwoFm8eLHx8fExmzZtMsb89vDD/v37m5tuusns2rXLfPXVV2bq1KmmcePGzjElJiaa+vXrm6FDh5o9e/aYffv2mZKSkjLj9NTnLTEx0fTo0cM5PWbMGHPLLbc4p6+66ioTHBxs5syZY7766iuzatUq43A4LI2pS5cu5o9//KPJyMgwX331lXnzzTfN3r17K9yGAOEGF5V169aZhg0bmsDAQNOvXz8zY8YMs2/fPpc+kszEiRNd2vr06WPuu+++Ctf7zDPPmOjoaOd0YmKiqVevnikoKHC2PfLII6ZPnz4VrmPUqFFmyJAhLm2PPPKI6dy5s3P6oYceKvNU9LPFxMSYO++8s8L5ERER5o9//KNzuqSkxDRr1qzSp6lbHV9BQYHx8/Mza9eudc4/fvy4qVevnjPcfP3118bhcJjvv//e5b0GDx5sZsyYYYwxplu3bmbOnDmVjvfssZ0dbh5//HHn9C+//GIcDod55513Kl1HZX8fd8ONJPP11187+9x7772mXr16prCw0Nk2dOhQc++997q893XXXedST3x8vImLizPGGPP++++b4ODgMuG8bdu25sUXXzTG/LZt/Pz8TG5uboVjNMZznzd3ws2VV17psszll19upk2b5vaYgoKCzKuvvlppHcDvcVgKF5Xhw4frhx9+UHJysoYOHarNmzerV69eevXVV136nX1ycUxMjDIyMpzT69at05VXXqmwsDA1aNBAs2bNUlZWlssykZGRCgoKck6Hh4crNze3wtoyMjLUv39/l7b+/fvr0KFDZQ5dVGbv3r0aPHhwpX26d+/u/LfD4VBYWJhLbec7viNHjuj06dO64oornPNDQkLUsWNH5/SePXtkjFGHDh3UoEED52vLli06fPiwJGnSpEl68skn1b9/fyUmJuqzzz5z++9Q3ljr16+voKCgSrfD2cuU9/dxR7169dS2bVvndGhoqCIjI9WgQQOXtrPXW9lnb/fu3frll1/UuHFjl79ZZmam828mSREREec8/8hTnzd3/P7vKbl+VtwZU0JCgiZMmKBrr71W8+fPdxkrUB5OKMZFJzAwUEOGDNGQIUM0e/ZsTZgwQYmJiRo7dmylyzkcDknSzp07NXLkSM2dO1dDhw5VSEiI3njjDZfzFSSVOYnT4XCopKSkwvUbY5zv8fs2q+rWrXvOPpXV5onxldZd2XhKSkrk4+Oj3bt3y8fHx6VfaQCYMGGChg4dqo0bN2rTpk1KSkrSggUL9OCDD55zjO7UWZVl6tSpU2Ysvz8fqbJ1VKWW0n7Sb3+z8PBwl/OSSl1yySXOf7tzxZinPm/uqGzc7oxpzpw5GjVqlDZu3Kh33nlHiYmJeuONN3TrrbdWS72o/dhzg4te586d9euvv7q07dy5s8z0pZdeKknavn27IiIiNHPmTPXu3Vvt27fXt99+65E6PvroI5e2tLQ0dejQocyPf2W6d++u999/v8p1eGJ8bdu2lZ+fnz755BNnW0FBgQ4dOuSc7tmzp4qLi5Wbm6t27dq5vMLCwpz9WrVqpYkTJ2r9+vWaOnWqXn755SqPzRNK94hkZ2c72/bu3eux9Vf22evVq5dycnLk6+tb5m/WpEkTS+/jqc/b+XJ3TB06dNCUKVO0adMm3XbbbVq5cuUFqxG1D3tucNHIy8vTH/7wB40bN07du3dXUFCQPv30Uz3zzDO65ZZbXPquXbtWvXv31pVXXqnVq1frk08+0fLlyyVJ7dq1U1ZWlt544w1dfvnl2rhxozZs2HDe9U2dOlWXX365nnjiCcXHx2vHjh1asmSJli5damk9iYmJGjx4sNq2bauRI0fqzJkzeuedd/Too4+6tbwnxhcUFKQxY8bokUceUaNGjdSsWTMlJiaqTp06zr0FHTp00J133qnRo0drwYIF6tmzp44dO6YPPvhA3bp10/XXX6/JkycrLi5OHTp00M8//6wPPvhAnTp1slSLp7Vr106tWrXSnDlz9OSTT+rQoUNl9mqdj+3bt+uZZ57RsGHDlJqaqrVr12rjxo2SpGuvvVYxMTEaNmyYnn76aXXs2FE//PCDUlJSNGzYMPXu3dvt9/HU5+18nWtMXbp00SOPPKLbb79dUVFR+u6777Rr1y4NHz78gtaJ2oU9N7hoNGjQQH369NGzzz6rgQMHqmvXrpo1a5buueceLVmyxKXv3Llz9cYbb6h79+5atWqVVq9erc6dO0uSbrnlFk2ZMkUPPPCALrvsMqWlpWnWrFnnXV+vXr305ptv6o033lDXrl01e/ZszZs375yHy8529dVXa+3atUpOTtZll12mQYMG6eOPP3Z7eU+Nb+HChYqJidGNN96oa6+9Vv3791enTp0UGBjo7LNy5UqNHj1aU6dOVceOHXXzzTfr448/VqtWrSRJxcXFuv/++9WpUyddd9116tix4wX/8T2bn5+fXn/9dX355Zfq0aOHnn76aT355JMeW//UqVO1e/du9ezZU0888YQWLFigoUOHSvrtcE5KSooGDhyocePGqUOHDho5cqS++eYbhYaGWnofT33ezte5xuTj46O8vDyNHj1aHTp00IgRIxQXF6e5c+de0DpRuzhMdR1kBWoph8OhDRs2cAt5D/v111/VokULLViwQOPHj/d2OQBsjMNSAKpFenq6vvzyS11xxRXKz8/XvHnzJKnMIUAA8DTCDYBq89e//lUHDx6Uv7+/oqOjtW3bNssnvgKAVRyWAgAAtsIJxQAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFYINwAAwFb+P1SvQKBu4JDFAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist([len(s.split())for s in ds_clean[\"subject\"]], bins=np.concatenate((np.linspace(0, 20, 21), [1e6])), cumulative=True, density=True);\n",
    "plt.xlim(0, 22)\n",
    "plt.ylim(0.0,1)\n",
    "plt.xlabel(\"Span of changes in number of lines\")\n",
    "plt.ylabel(\"Cumulative fraction\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "FULL_RANGE_FRAC = 0.2\n",
    "RANGE=32\n",
    "\n",
    "def prepare_code(example):\n",
    "    if np.random.random()<0.2:\n",
    "        example[\"content\"] = f\"<commit_before>{example['old_contents']}<commit_msg>{example['subject']}<commit_after>{example['new_contents']}\"\n",
    "        example[\"size\"] = len(example[\"content\"])\n",
    "    else:\n",
    "        start_offset = np.random.randint(0, RANGE)\n",
    "        end_offset = np.random.randint(0, RANGE)\n",
    "\n",
    "        old_lines = example[\"old_contents\"].splitlines()\n",
    "        new_lines = example[\"new_contents\"].splitlines()\n",
    "\n",
    "        old_start = max(0, example[\"old_change_start\"]- start_offset)\n",
    "        new_start = max(0, example[\"new_change_start\"]- start_offset)\n",
    "\n",
    "        old_end = min(len(old_lines), example[\"old_change_end\"] + end_offset)\n",
    "        new_end = min(len(new_lines), example[\"new_change_end\"] + end_offset)\n",
    "\n",
    "        code_before = \"\\n\".join(old_lines[old_start:old_end])\n",
    "        code_after = \"\\n\".join(new_lines[new_start:new_end])\n",
    "        example[\"content\"] = f\"<commit_before>{code_before}<commit_msg>{example['subject']}<commit_after>{code_after}\"\n",
    "        example[\"size\"] = len(example[\"content\"])\n",
    "    return example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8276273\n"
     ]
    }
   ],
   "source": [
    "uniques = set([r+\"/\"+filename for filename, r in zip(ds_clean[\"old_file\"], ds_clean[\"repos\"])])\n",
    "print(len(uniques))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes'],\n",
       "    num_rows: 12249044\n",
       "})"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_clean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(\"programming-languages.json\", \"r\") as f:\n",
    "    file_exts = json.load(f)\n",
    "\n",
    "exts = set(itertools.chain.from_iterable(file_exts.values()))\n",
    "exts = {e.strip(\".\") for e in exts}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [],
   "source": [
    "def check_uniques(example, uniques):\n",
    "    \"\"\"Check if current hash is still in set of unique hashes and remove if true.\"\"\"\n",
    "    if example[\"repos\"]+\"/\"+example[\"old_file\"] in uniques:\n",
    "        uniques.remove(example[\"repos\"]+\"/\"+example[\"old_file\"])\n",
    "        return True\n",
    "    else:\n",
    "        return False\n",
    "\n",
    "def check_exts(example, exts):\n",
    "    if example[\"old_file\"].split(\".\")[-1] in exts:\n",
    "        return True\n",
    "    if example[\"old_file\"].endswith(\"Dockerfile\") or example[\"old_file\"].endswith(\"Makefile\"):\n",
    "        return True\n",
    "    return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ds_clean = ds_clean.filter(check_exts, fn_kwargs={\"exts\": exts}, num_proc=30)\n",
    "ds_clean = ds_clean.filter(check_uniques, fn_kwargs={\"uniques\": uniques}, num_proc=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes'],\n",
       "    num_rows: 8273154\n",
       "})"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_clean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4ee075beaab74d1cbc28be4091f0ca7d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Map (num_proc=30):   0%|          | 0/8273154 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ds_clean = ds_clean.map(prepare_code, num_proc=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "68.352518077"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sum(ds_clean[\"size\"])/1000/1000/1000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "opt_out_github_login_the_stack_12 = set([el.lower() for el in opt_out_github_login_the_stack_12])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['keeguon/activerecord-jdbc-adapter',\n",
       " 'jruby/activerecord-jdbc-adapter',\n",
       " 'bruceadams/activerecord-jdbc-adapter',\n",
       " 'bruceadams/activerecord-jdbc-adapter',\n",
       " 'keeguon/activerecord-jdbc-adapter',\n",
       " 'kares/activerecord-jdbc-adapter',\n",
       " 'kares/activerecord-jdbc-adapter',\n",
       " 'jruby/activerecord-jdbc-adapter',\n",
       " 'jruby/activerecord-jdbc-adapter',\n",
       " 'bruceadams/activerecord-jdbc-adapter',\n",
       " 'keeguon/activerecord-jdbc-adapter',\n",
       " 'kares/activerecord-jdbc-adapter']"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_clean[0][\"repos\"].split(\",\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [],
   "source": [
    "def filter_opt_out(example):\n",
    "    repo_names = example[\"repos\"].split(\",\")\n",
    "    try:\n",
    "        repo_owners = [repo_name.split(\"/\")[0].lower() for repo_name in repo_names]\n",
    "    except:\n",
    "        print(example[\"repos\"])\n",
    "    filtered_repo_names = [repo_name for repo_name, repo_owner in zip(repo_names, repo_owners) if repo_owner not in opt_out_github_login_the_stack_12]\n",
    "\n",
    "    if len(filtered_repo_names)>0:\n",
    "        example[\"repos\"] = \",\".join(filtered_repo_names)\n",
    "        example[\"drop_opt_out\"] = False\n",
    "    else:\n",
    "        example[\"repos\"] = \"\"\n",
    "        example[\"drop_opt_out\"] = True\n",
    "    return example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading cached processed dataset at /home/leandro/.cache/huggingface/datasets/json/data-97311ba745a469ed/0.0.0/0f7e3662623656454fcd2b650f34e886a7db4b9104504885bd462096cc7a9f51/cache-521c393b44ec863a_*_of_00030.arrow\n"
     ]
    }
   ],
   "source": [
    "ds_opt_out = ds_clean.map(filter_opt_out, num_proc=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes', 'content', 'size', 'drop_opt_out'],\n",
       "    num_rows: 8273154\n",
       "})"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_opt_out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "66"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sum(ds_opt_out[\"drop_opt_out\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading cached processed dataset at /home/leandro/.cache/huggingface/datasets/json/data-97311ba745a469ed/0.0.0/0f7e3662623656454fcd2b650f34e886a7db4b9104504885bd462096cc7a9f51/cache-58a8158cf224b45e_*_of_00030.arrow\n"
     ]
    }
   ],
   "source": [
    "ds_opt_out = ds_opt_out.filter(lambda x: not x[\"drop_opt_out\"], num_proc=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes', 'content', 'size', 'drop_opt_out'],\n",
       "    num_rows: 8273088\n",
       "})"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_opt_out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "\n",
    "c = Counter([x.split(\".\")[-1] for x in ds_opt_out[\"old_file\"]]).most_common()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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rVtLZfbu3as2pT4+Ph5OTk5wcXHR5dSJiIioGtIpCPXp0wezZ8/Gjh07cPXqVcTGxiIyMhL9+/cH8PRyU2hoKCIiIhAbG4vk5GQEBgbCzMwM/v7+AACVSoWRI0diwoQJ2L17N44fP46hQ4eiWbNm0iyyJk2aoFevXggKCsKhQ4dw6NAhBAUFoXfv3nBzcwMA+Pj4wN3dHQEBATh+/Dh2796NiRMnIigoCFZWVgCeTsFXKpUIDAxEcnIyYmNjERERUeqMMSIiIpIXncYILVmyBJ999hmCg4ORnp4OJycnfPjhh5g+fbpUZtKkScjJyUFwcDAyMjLQrl07xMfHw9LSUiqzaNEiGBoaYtCgQcjJyUG3bt0QHR0NAwMDqcymTZswduxYaXaZn58fli5dKj1vYGCAHTt2IDg4GJ06dYKpqSn8/f2xYMECqYxKpcLOnTsREhKCNm3awMbGBmFhYQgLC9P9lSIiIqJqRyG4zHKZsrKyoFKpkJmZKfU0VcSd38tbB+8+T0REVLqSPr9LwnuNERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsGVZ2A6jyuEzZUebzV+f6vqSWEBERVQ72CBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFs6RyEbty4gaFDh8LW1hZmZmbw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NPXq1SvxEt+hQ4eEi4uLxjY8evRIuhQgxNMBsYsWLdKp+728+vTpI2xsbMSWLVuEEE8vBcyYMUMYGxuLCRMmaFVHaTN8rl69qnFwbJHnZ/h07NhRpxk+c+fOVbu8P3DgQFGjRg1Rp04drS5tWVhYVImJBOUVEREhVq9eXWz76tWrxdy5c7WqozyzrZ48eSL27NmjNglBW7GxscLBwaFC3quFEMLOzq5c71WlTULIysoSI0aM0KqOixcvimnTponBgwdLkwF+++23Escnaos9QnpavXo1Fi1ahAsXLgB4mrxDQ0Px/vvva11Hamoqli9fLnUdu7u7Y9SoUVp3tZaloKAAycnJpa67YmxsDEdHR/j7+2Po0KHw8PDQ+Rh5eXnw8fHBihUr4Obmplc7NfWoPKuk//7mz5+PmzdvIioqSq/jA0Dt2rWxd+9evbtWL126hKioKLX1e8aNG4fXX39dq/0r4hyevbTzLIVCARMTE7i6uqJv377FFiKrakxMTHDmzBnUr19fbfvly5fh7u6Ox48fl7l/RS42Wh7Lly/HxIkT4efnh6tXryIlJQXR0dHo3r17mfsV/Ry//PJLBAUFqV1GKygokNau2b9/v8Y21KlTBz/99BPatGmDH3/8ESEhIfjzzz+xfv16/PnnnxrraNCgATZu3IiOHTti586dGDRoEL799lt89913SElJ0biSfb9+/RAQEKBxjZyXYcOGDVixYgUuX76MgwcPol69eli0aBEaNGigsRejItbXeu211/Djjz/q/bMo7e9CW9nZ2bCyssK5c+dKvTSmzVpEEyZMgJGREebOnatXO8orISEBb7/9Njp16oS9e/fizJkzaNCgAebPn48jR47ghx9+0KteBiE9fPbZZ1i0aBHGjBmDDh06AAAOHjyIpUuXYty4cfj888+1qufx48f4559/ShyX8qIXArxz5w5iYmKwZcsWHDx4EB4eHhg6dCj8/f2LdemXpVatWjh48KA0NuplKywshK+vL86fPw93d3etx4Q8qzxB5Pfff4efnx88PT3RqVMnCCFw4MABnDhxAj///DN69OjxUs6ha9euOHbsGAoKCuDm5gYhBC5cuAADAwM0btxYWo123759cHd31/k8tZWRkYHVq1erhcLhw4drHcAaNmyIGTNmYOjQoWrbN2zYgBkzZmhcjLAiFhutKFOnTsW8efNg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69eXeOuNqqq89/HLy8sT/v7+Uk9W0R0Whg4dqtYTrSsOltZDRaw58ujRIwwcOBC1atVCs2bNio1LGTt2bLnbWZaOHTtiyJAhePfddzWuG/QijRw5Em+88YbG9YZK07JlS1y6dAlCCLi4uBR7HUtbaOxZa9euRVxcHNauXavVYnfPEkIgKioKCxcuxM2bNwEATk5O+PjjjzF27Fit/gOriHPIzs7G+PHjsX79ejx58gQAYGhoiPfeew+LFi2Cubk5kpKSAACenp46naO2yrsmVHVRo0YNaUzEs65du4amTZsiOzv7pbSjvDN8yjtbavbs2YiKioKvr6/e73FFs6tmzZqFYcOG4auvvsKNGzewYsUKzJ07V+se+FWrVuHzzz9HamoqgKcz6sLDw0tcoPNFGDt2LFxdXYud89KlS3Hx4kWN46K2bt2KgIAADBkyBBs2bMDp06fRoEEDfP311/jll1+0uut6p06d4OXlBW9vb3Tq1KnYOKOXoXbt2pg/fz4CAgLKVc+lS5dw/PhxFBYWomXLluVaTBHgrLFK880332DUqFEwNTUtNkBWoVBonB3zKlu8eLH09cOHDxEZGan3m6WmRcdKW2jsWRURRADgwYMHACAN1tVWRZxDkezsbFy+fBlCCLz++uvS5YyXoaRVtp+l64rbr5qKnPpeEfSZ4fOs8s6WKmuqt7bvcXXr1sX69evh7e0NKysrHDt2DK6urtiwYQO2bNlSagB4dqbSs+7cuYPCwsJyra6sjzp16mD79u1o3bq12vZjx47Bz88P169fL3P/li1bYvz48dLCg0WzpZKSktCrVy+kpaVpbMOcOXOQkJCAAwcO4PHjx2jdurUUjDp37vxS3itsbW1x5MiRcg8FAIov1loeHCNUST799FPMmjULU6ZM0fgB8iKdPn0aKSkpxcaOvMjp+4sWLVL73sLCAgkJCUhISFDbrlAoNAahK1euYPjw4VrNSCpN37599f5jysnJgRACZmZmsLS0xLVr17B69Wq4u7vDx8dHqzo6depU6voyK1as0Kk9FhYWldbbos16KtVZ0aq4QgicPHmy2NT3Fi1aaDVLqaKUd/xeeWdLVcTvw71796TjW1lZSdPlO3fuXOaaUP3790daWhpq1aqltkp3ZfV+3717t8R1eqysrHDnzh2N+587d67ElZ+trKxw//59rdowdepUTJ06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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame.from_dict({\"lang\":dict(c[:30]).keys(), \"freq\": dict(c[:30]).values()})\n",
    "ax_ = df.plot.bar(x='lang', y='freq', rot=90)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [],
   "source": [
    "DATA_SAMPLING = .5\n",
    "DATA_EXT = {\"json\", \"yml\", \"xml\", \"html\", \"yaml\"}\n",
    "\n",
    "def subsample_extensions(example):\n",
    "    if example[\"old_file\"].split(\".\")[-1] in DATA_EXT:\n",
    "        if random.random()>DATA_SAMPLING:\n",
    "            return False\n",
    "        \n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d3a3211be08141b3997f4a277d464d23",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Filter (num_proc=30):   0%|          | 0/8273088 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ds_opt_out = ds_opt_out.filter(subsample_extensions, num_proc=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes', 'content', 'size', 'drop_opt_out'],\n",
       "    num_rows: 7674345\n",
       "})"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_opt_out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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c2epzKFDh9Sm1EdFRcHGxgZ2dnYVeelERET0EqpQEBo8eDAWLlyIvXv34tq1a4iIiEBISAiGDRsGoPB0U0BAAIKDgxEREYGEhAT4+PjAwMAAXl5eAACVSoUJEyZg+vTpOHDgAE6dOoUxY8agXbt20iyyNm3aYODAgfD19UVsbCxiY2Ph6+uLQYMGwcHBAQDg7u4OR0dHeHt749SpUzhw4ABmzJgBX19fmJiYACicgq9UKuHj44OEhAREREQgODi41BljREREJC8VGiO0atUqfPLJJ/Dz80NaWhpsbGzw/vvvY968eVKZmTNnIjs7G35+fkhPT0fXrl0RFRUFY2NjqcyKFSugra2NkSNHIjs7G3379kVYWBi0tLSkMtu3b8eUKVOk2WWenp5YvXq19LiWlhb27t0LPz8/9OzZE/r6+vDy8sKyZcukMiqVCvv27YO/vz9cXFxgZmaGwMBABAYGVvxIERER0UtHIbjMcpkyMzOhUqmQkZEh9TRVx5Xfq7oPXn2eiIiodCV9f5eE1xojIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItliECIiIiLZYhAiIiIi2WIQIiIiItnSrusGUN2xm723zMevLfaopZYQERHVDfYIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWxVOAjdvHkTY8aMgbm5OQwMDODs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2xdnzpxBfHy8dHNxccHo0aMRHx+PFi1awNraGvv27ZPq5ObmIjo6Gj169AAAdO7cGTo6Omplbt++jYSEBKlM9+7dkZGRgePHj0tljh07hoyMDLUyCQkJuH37tlQmKioKSqUSnTt3lsocOnRIbUp9VFQUbGxsYGdnV5GXTkRERC+hCs0aMzY2hpOTk9o2Q0NDmJubS9sDAgIQHByMli1bomXLlggODoaBgQG8vLwAACqVChMmTMD06dNhbm6Ohg0bYsaMGWjXrp00+LpNmzYYOHAgfH19sW7dOgDAe++9h0GDBsHBwQEA4O7uDkdHR3h7e+Pzzz/H/fv3MWPGDPj6+kq9OF5eXvj000/h4+ODjz76CBcvXkRwcDDmzZvHGWNERERU/StLz5w5E9nZ2fDz80N6ejq6du2KqKgoGBsbS2VWrFgBbW1tjBw5EtnZ2ejbty/CwsKgpaUlldm+fTumTJkizS7z9PTE6tWrpce1tLSwd+9e+Pn5oWfPntDX14eXlxeWLVsmlVGpVNi3bx/8/f3h4uICMzMzBAYGIjAwsLpfNhEREb2AqhyEDh48qHZfoVAgKCgIQUFBpdbR09PDqlWrsGrVqlLLNGzYENu2bSvzuZs2bYpffvmlzDLt2rXDoUOHyixDRERE8sSLrhIREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgRERGRbDEIERERkWwxCBEREZFsMQgR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PzAwMICHh4d0yY2y7Nq1Czdv3sSkSZPw/fffo1mzZnjzzTfx/fffIy8vr9Lt4hghKhW/dF5+RRcaBYCCgoIqLZ9P9LxnL5uio6ODfv36VeiUzrRp0xAdHY09e/agZ8+eAAovSzFlyhRMnz4da9asqY2XUefqwzil6mBra4ujR4+iYcOGiIyMRHh4OAAgPT1d40kW5ubmmDp1KqZOnYpTp07hm2++wdixY2FkZIQxY8bAz89P46vZF2EQIpKxoguNFnF2dgZQN4t80svn5MmT0iDWH374AVZWVjh16hR27dqFefPmlRuEdu3ahR9++AFubm7Strfeegv6+voYOXKkbILQvHnz4OXlhWnTpqFv377SdbqioqKkhXlfBAEBARg9ejSMjIzQrFkz6f/10KFDaNeuXYX2VZlFW0vDwdJERFQjqjr13MDAAHFxcWjTpo3a9rNnz6JLly6yGjSfmpqK27dvo0OHDtIpuuPHj8PExKTWTtFVh7///hspKSno37+/NAtu7969MDU1lXr9SpOXl4c9e/Zg06ZNiIqKQvv27fHuu+9i9OjR0qnD8PBwfPDBB0hPT9e4TQxCRERUI4q+qIYNGwYnJydERkaie/fuiIuLg4eHB1JTU8us37dvX5ibm2PLli3SqZOicUf379+v9Lox9GKysLBAQUEBRo0aBV9fX6kH+1np6eno1KkTrl69qvF+GYSIiKhGVHXq+ZkzZ/Dmm2/iyZMn6NChAxQKBeLj46FUKhEVFYW2bdvWxsugaiKEwA8//IA///yzxEVbd+/eXWb9yizaqgkGISIiqjFVPaWTnZ2Nbdu24cKFCxBCwNHREaNHj4a+vn5NN52q2ZQpU7B+/Xr06dMHVlZWxcYebtq0qU7axSBERET10qJFi2BlZYXx48erbf/mm29w584dzJo1q45aRpXRsGFDbNu2DW+99VZdN0UN1xEiIqJ6ad26dSX2GrVt2xZr166tgxZRVahUqlIvrVKXGISIiKheSk1NRePGjYttb9SoEW7fvl0HLaKqCAoKwqeffors7Oy6booariNERET1kq2tLQ4fPozmzZurbT98+DBsbGzqqFVUWSNGjMDOnTthaWkJOzu7You2njx5sk7axSBERET10rvvvouAgADk5eWpXbR15syZmD59eh23jirKx8cHcXFxGDNmTImDpesKB0sTEVG9JITA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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "c = Counter([x.split(\".\")[-1] for x in ds_opt_out[\"old_file\"]]).most_common()\n",
    "c\n",
    "df = pd.DataFrame.from_dict({\"lang\":dict(c[:30]).keys(), \"freq\": dict(c[:30]).values()})\n",
    "ax_ = df.plot.bar(x='lang', y='freq', rot=90)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "64.448053264"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sum(ds_opt_out[\"size\"])/1000/1000/1000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'subject', 'message', 'repos', 'old_file', 'new_file', 'new_contents', 'old_contents', 'returncode', 'stderr', 'old_change_start', 'old_change_end', 'old_change_range', 'new_change_start', 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes', 'content', 'size', 'drop_opt_out'],\n",
       "    num_rows: 7674345\n",
       "})"
      ]
     },
     "execution_count": 112,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_opt_out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [],
   "source": [
    "ds_final = ds_opt_out.remove_columns([\"subject\", \"message\", \"new_contents\", \"old_contents\", \"returncode\", \"stderr\", \"old_change_start\", \"old_change_end\", \"old_change_range\", \"new_change_start\", 'new_change_end', 'new_change_range', 'n_inserts', 'n_deletes', 'n_changes', \"size\",'drop_opt_out'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Dataset({\n",
       "    features: ['commit', 'repos', 'old_file', 'new_file', 'content'],\n",
       "    num_rows: 7674345\n",
       "})"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_final"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ds_final.push_to_hub(\"git-commits-cleaned\", private=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'commit': '9fbfcc964b11e807c7e00a910acaaafabfa18316',\n",
       " 'old_file': 'lib/arjdbc/postgresql/connection_methods.rb',\n",
       " 'new_file': 'lib/arjdbc/postgresql/connection_methods.rb',\n",
       " 'content': '<commit_before>ArJdbc::ConnectionMethods.module_eval do\\n  def postgresql_connection(config)\\n    begin\\n      require \\'jdbc/postgres\\'\\n      ::Jdbc::Postgres.load_driver(:require) if defined?(::Jdbc::Postgres.load_driver)\\n    rescue LoadError # assuming driver.jar is on the class-path\\n    end\\n\\n    host = config[:host] ||= ( config[:hostaddr] || ENV[\\'PGHOST\\'] || \\'localhost\\' )\\n    port = config[:port] ||= ( ENV[\\'PGPORT\\'] || 5432 )\\n    database = config[:database] || config[:dbname] || ENV[\\'PGDATABASE\\']\\n\\n    config[:url] ||= \"jdbc:postgresql://#{host}:#{port}/#{database}\"\\n    config[:url] << config[:pg_params] if config[:pg_params] # should go away\\n\\n    config[:username] ||= ( config[:user] || ENV[\\'PGUSER\\'] || ENV_JAVA[\\'user.name\\'] )\\n    config[:password] ||= ENV[\\'PGPASSWORD\\'] unless config.key?(:password)\\n    properties = ( config[:properties] ||= {} )\\n    # PG :connect_timeout - maximum time to wait for connection to succeed\\n    if connect_timeout = ( config[:connect_timeout] || ENV[\\'PGCONNECT_TIMEOUT\\'] )\\n      properties[\\'socketTimeout\\'] ||= connect_timeout\\n      # NOTE: maybe set options[\\'loginTimeout\\'] as well?\\n    end\\n    sslmode = config.key?(:sslmode) ? config[:sslmode] : config[:requiressl]\\n    # NOTE: makes not much sense since this needs some JVM options :\\n    # sslmode = ENV[\\'PGSSLMODE\\'] || ENV[\\'PGREQUIRESSL\\'] if sslmode.nil?\\n    unless sslmode.nil? # PG :sslmode - disable|allow|prefer|require\\n      # JRuby/JVM needs to be started with :\\n      #  -Djavax.net.ssl.trustStore=mystore -Djavax.net.ssl.trustStorePassword=...\\n      # or a non-validating connection might be used (for testing) :\\n      #  :sslfactory = \\'org.postgresql.ssl.NonValidatingFactory\\'\\n      properties[\\'ssl\\'] ||= \\'true\\' if sslmode == true || sslmode.to_s == \\'require\\'\\n    end\\n    properties[\\'tcpKeepAlive\\'] ||= config[:keepalives] if config.key?(:keepalives)\\n    properties[\\'kerberosServerName\\'] ||= config[:krbsrvname] if config[:krbsrvname]\\n\\n    config[:driver] ||= defined?(::Jdbc::Postgres.driver_name) ? ::Jdbc::Postgres.driver_name : \\'org.postgresql.Driver\\'\\n    config[:adapter_spec] ||= ::ArJdbc::PostgreSQL\\n    config[:adapter_class] = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter unless config.key?(:adapter_class)\\n\\n    jdbc_connection(config)\\n  end\\n  alias_method :jdbcpostgresql_connection, :postgresql_connection\\nend\\n<commit_msg>[postgres] support :login_timeout as a standalone config option<commit_after>ArJdbc::ConnectionMethods.module_eval do\\n  def postgresql_connection(config)\\n    begin\\n      require \\'jdbc/postgres\\'\\n      ::Jdbc::Postgres.load_driver(:require) if defined?(::Jdbc::Postgres.load_driver)\\n    rescue LoadError # assuming driver.jar is on the class-path\\n    end\\n\\n    host = config[:host] ||= ( config[:hostaddr] || ENV[\\'PGHOST\\'] || \\'localhost\\' )\\n    port = config[:port] ||= ( ENV[\\'PGPORT\\'] || 5432 )\\n    database = config[:database] || config[:dbname] || ENV[\\'PGDATABASE\\']\\n\\n    config[:url] ||= \"jdbc:postgresql://#{host}:#{port}/#{database}\"\\n    config[:url] << config[:pg_params] if config[:pg_params] # should go away\\n\\n    config[:username] ||= ( config[:user] || ENV[\\'PGUSER\\'] || ENV_JAVA[\\'user.name\\'] )\\n    config[:password] ||= ENV[\\'PGPASSWORD\\'] unless config.key?(:password)\\n    properties = ( config[:properties] ||= {} )\\n    # PG :connect_timeout - maximum time to wait for connection to succeed\\n    if connect_timeout = ( config[:connect_timeout] || ENV[\\'PGCONNECT_TIMEOUT\\'] )\\n      properties[\\'socketTimeout\\'] ||= connect_timeout\\n    end\\n    if login_timeout = config[:login_timeout]\\n      properties[\\'loginTimeout\\'] ||= login_timeout\\n    end\\n    sslmode = config.key?(:sslmode) ? config[:sslmode] : config[:requiressl]\\n    # NOTE: makes not much sense since this needs some JVM options :\\n    # sslmode = ENV[\\'PGSSLMODE\\'] || ENV[\\'PGREQUIRESSL\\'] if sslmode.nil?\\n    unless sslmode.nil? # PG :sslmode - disable|allow|prefer|require\\n      # JRuby/JVM needs to be started with :\\n      #  -Djavax.net.ssl.trustStore=mystore -Djavax.net.ssl.trustStorePassword=...\\n      # or a non-validating connection might be used (for testing) :\\n      #  :sslfactory = \\'org.postgresql.ssl.NonValidatingFactory\\'\\n      properties[\\'ssl\\'] ||= \\'true\\' if sslmode == true || sslmode.to_s == \\'require\\'\\n    end\\n    properties[\\'tcpKeepAlive\\'] ||= config[:keepalives] if config.key?(:keepalives)\\n    properties[\\'kerberosServerName\\'] ||= config[:krbsrvname] if config[:krbsrvname]\\n\\n    config[:driver] ||= defined?(::Jdbc::Postgres.driver_name) ? ::Jdbc::Postgres.driver_name : \\'org.postgresql.Driver\\'\\n    config[:adapter_spec] ||= ::ArJdbc::PostgreSQL\\n    config[:adapter_class] = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter unless config.key?(:adapter_class)\\n\\n    jdbc_connection(config)\\n  end\\n  alias_method :jdbcpostgresql_connection, :postgresql_connection\\nend\\n'}"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ds_final[0]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.12"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "d4d1e4263499bec80672ea0156c357c1ee493ec2b1c70f0acce89fc37c4a6abe"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
